package com.cnswhy.cloud.server.app.controller.customer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cnswhy.cloud.common.core.exception.BizException;
import com.cnswhy.cloud.common.core.mybatis.conditions.Wraps;
import com.cnswhy.cloud.common.core.utils.AliUploadFileUtils;
import com.cnswhy.cloud.common.core.utils.CnswhyUtil;
import com.cnswhy.cloud.common.core.utils.Kits;
import com.cnswhy.cloud.common.rabbitmq.service.MessageService;
import com.cnswhy.cloud.common.redis.annotation.RedisLock;
import com.cnswhy.cloud.common.redis.model.LockTimeoutStrategy;
import com.cnswhy.cloud.common.redis.service.IdGeneratorService;
import com.cnswhy.cloud.common.redis.service.RedisService;
import com.cnswhy.cloud.server.app.controller.BaseController;
import com.cnswhy.cloud.server.app.dto.QuerySplitValueDTO;
import com.cnswhy.cloud.server.app.exception.LoginExecption;
import com.cnswhy.cloud.server.app.utils.FileUtil;
import com.cnswhy.cloud.server.app.utils.FtpUtil;
import com.cnswhy.cloud.server.app.utils.RSAUtils;
import com.cnswhy.cloud.server.common.entity.constant.AmqpExchange;
import com.cnswhy.cloud.server.common.entity.enumeration.*;
import com.cnswhy.cloud.server.common.entity.mq.UpdateCustomerSplitMQ;
import com.cnswhy.cloud.server.core.base.BankService;
import com.cnswhy.cloud.server.core.channel.hcpay.dto.BankCardVerifyDto;
import com.cnswhy.cloud.server.core.channel.hcpay.dto.BankCardVerifyResponseDto;
import com.cnswhy.cloud.server.core.channel.hcpay.service.HcpayService;
import com.cnswhy.cloud.server.core.constant.RedisConstant;
import com.cnswhy.cloud.server.core.dao.WalletTransDtlMapper;
import com.cnswhy.cloud.server.core.dto.CustomerRegistDto;
import com.cnswhy.cloud.server.core.entity.*;
import com.cnswhy.cloud.server.core.query.QueryGenerator;
import com.cnswhy.cloud.server.core.service.*;
import com.cnswhy.cloud.server.core.service.app.NoticeReadService;
import com.cnswhy.cloud.server.core.service.customer.CouponDetailService;
import com.cnswhy.cloud.server.core.service.customer.CustomerBankService;
import com.cnswhy.cloud.server.core.service.customer.CustomerService;
import com.cnswhy.cloud.server.core.utils.BaiduAip.Bankcard;
import com.cnswhy.cloud.server.core.utils.BaiduAip.Idcard;
import com.cnswhy.cloud.server.core.utils.PasswordCoder;
import com.cnswhy.cloud.server.core.vo.RespVo;
import com.cnswhy.cloud.server.core.wallet.WalletService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Slf4j

@Api(tags = "服务商管理-分润模块")
@Controller
@RequestMapping("/customerSplit")
public class CustomerSplitController extends BaseController {

    @Autowired
    RedisService redisService;
    @Autowired
    CustomerSplitService customerSplitService;
    @Autowired
    MessageService messageService;
    @Autowired
    CustomerService customerService;
    @Autowired
    CpsBankRateSplitService cpsBankRateSplitService;
    @ApiOperation(value = "查询分润类型", httpMethod = "POST")
    @RequestMapping(value = "/getSplitType", method = {RequestMethod.POST})
    @ResponseBody
    public RespVo getSplitType(HttpServletRequest request) {
        return RespVo.success(SplitType.values());
    }
    @ApiOperation(value = "查看自己的收益能力详情", httpMethod = "POST")
    @RequestMapping(value = "/queryUpSplit", method = {RequestMethod.POST})
    @ResponseBody
    public RespVo queryUpSplit(HttpServletRequest request, QuerySplitValueDTO querySplitValueDTO) {
        try {
            Customer loginCustomer = getLoginCustomer(request);
            CustomerSplit customerSplit = customerSplitService.getOne(Wraps.<CustomerSplit>lbQ()
                    .eq(CustomerSplit::getSplitType,querySplitValueDTO.getSplitType())
                    .eq(CustomerSplit::getDownCustomerId,loginCustomer.getId()));
            List<CpsBankRateSplit> cpsBankRateSplits = cpsBankRateSplitService.list();
            JSONArray jsonArray = new JSONArray();
            for(CpsBankRateSplit cpsBankRateSplit : cpsBankRateSplits ){
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("bankAbbr", cpsBankRateSplit.getBankAbbr());
                jsonObject.put("bankName", cpsBankRateSplit.getBankName());
                BigDecimal downRate = BigDecimal.valueOf(60).subtract(BigDecimal.valueOf(cpsBankRateSplit.getFeeRate().doubleValue())).multiply(customerSplit.getCurrRate()).divide(BigDecimal.valueOf(100));
                BigDecimal currRate = BigDecimal.valueOf(60).subtract(BigDecimal.valueOf(cpsBankRateSplit.getFeeRate().doubleValue())).multiply(customerSplit.getUpRate()).divide(BigDecimal.valueOf(100));
                jsonObject.put("curr", String.format("万%.2f", currRate.doubleValue()));
                jsonObject.put("down", String.format("万%.2f", downRate.doubleValue()));
                jsonArray.add(jsonObject);
            }
            return RespVo.success(jsonArray);
        } catch (BizException e) {
            return RespVo.fail(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return RespVo.fail("查询收益能力详情失败");
        }
    }
    @ApiOperation(value = "查看下级收益能力详情", httpMethod = "POST")
    @RequestMapping(value = "/querySplitValue", method = {RequestMethod.POST})
    @ResponseBody
    public RespVo querySplitValue(HttpServletRequest request, QuerySplitValueDTO querySplitValueDTO) {
        try {
            Customer loginCustomer = getLoginCustomer(request);
            CustomerSplit customerSplit = customerSplitService.getOne(Wraps.<CustomerSplit>lbQ().eq(CustomerSplit::getCustomerId,loginCustomer.getId())
                    .eq(CustomerSplit::getSplitType,querySplitValueDTO.getSplitType())
                    .eq(CustomerSplit::getDownCustomerId,querySplitValueDTO.getDownCustomerId()));
            List<CpsBankRateSplit> cpsBankRateSplits = cpsBankRateSplitService.list();
            JSONArray jsonArray = new JSONArray();
            for(CpsBankRateSplit cpsBankRateSplit : cpsBankRateSplits ){
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("bankAbbr", cpsBankRateSplit.getBankAbbr());
                jsonObject.put("bankName", cpsBankRateSplit.getBankName());
                BigDecimal downRate = BigDecimal.valueOf(60).subtract(BigDecimal.valueOf(cpsBankRateSplit.getFeeRate().doubleValue())).multiply(customerSplit.getCurrRate()).divide(BigDecimal.valueOf(100));
                BigDecimal currRate = BigDecimal.valueOf(60).subtract(BigDecimal.valueOf(cpsBankRateSplit.getFeeRate().doubleValue())).multiply(customerSplit.getUpRate()).divide(BigDecimal.valueOf(100));
                jsonObject.put("curr", String.format("万%.2f", currRate.doubleValue()));
                jsonObject.put("down", String.format("万%.2f", downRate.doubleValue()));
                jsonArray.add(jsonObject);
            }
            return RespVo.success(jsonArray);
        } catch (BizException e) {
            return RespVo.fail(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return RespVo.fail("查询收益能力详情失败");
        }
    }
    @ApiOperation(value = "自定义费率", httpMethod = "POST")
    @RequestMapping(value = "/setSplit", method = {RequestMethod.POST})
    @ResponseBody
    public RespVo setSplit(Long split, HttpServletRequest request, Long downCustomerId, String downCustomertPhone, SplitType splitType) {
        log.info("设置自定义费率:{} {} {}", split, downCustomerId, downCustomertPhone);
        RespVo vo = new RespVo();
        try {
            Customer loginCustomer = getLoginCustomer(request);
            CustomerSplit currSplit = customerSplitService.getOne(Wraps.<CustomerSplit>lbQ().eq(CustomerSplit::getDownCustomerId,loginCustomer.getId())
                .eq(CustomerSplit::getSplitType,splitType));
            if(currSplit.getSplitRate() <= 0){
                throw new BizException("上级未设置本级服务商收益");
            }
            CustomerSplit customerSplit = customerSplitService.getOne(Wraps.<CustomerSplit>lbQ().eq(CustomerSplit::getCustomerId,loginCustomer.getId())
                    .eq(CustomerSplit::getSplitType,splitType)
                    .eq(CustomerSplit::getDownCustomerId,downCustomerId));
            if(customerSplit == null){
                customerSplit = new CustomerSplit();
                customerSplit.setCustomerId(loginCustomer.getId());
                customerSplit.setSplitRate(0L);
                customerSplit.setSplitType(splitType);
                customerSplit.setDownCustomerId(downCustomerId);
                customerSplit.setDownCustomerPhone(downCustomertPhone);
                customerSplit.setStatus("0");
                customerSplitService.save(customerSplit);
            }
            if(split.compareTo(100L) > 0 || split.compareTo(0L) < 0){
                throw new BizException("下级费率设置在0-100间");
            }
            customerSplit.setSplitRate(split);
            customerSplit.setStatus("1");
            customerSplit.setCurrRate(currSplit.getCurrRate().multiply(BigDecimal.valueOf(split.doubleValue() / 100)));
            customerSplit.setUpRate(currSplit.getCurrRate().subtract( customerSplit.getCurrRate()));
            customerSplitService.updateById(customerSplit);
            //更新分润链
            UpdateCustomerSplitMQ updateCustomerSplitMQ = UpdateCustomerSplitMQ.builder().customerId(customerSplit.getDownCustomerId()).splitType(splitType).build();
            messageService.sendQueueByObject(AmqpExchange.UPDATE_CUSTOMER_SPLIT_MESSAGE,updateCustomerSplitMQ);
            vo.setCode(RespVo.CODE_SUCCESS);
        } catch (BizException e) {
            vo.setCode(RespVo.CODE_ERROR);
            vo.setMessage(e.getMessage());
        } catch (Exception e) {
            vo.setCode(RespVo.CODE_ERROR);
            vo.setMessage("操作失败");
            log.error("操作失败", e);
        }
        return vo;
    }
    @ApiOperation(value = "查询自定义费率及上级自定义费率", httpMethod = "POST")
    @RequestMapping(value = "/getSplit",method = {RequestMethod.POST})
    @ApiParam(name = "type", value = "1:已设置 0:未设置")
    @ResponseBody
    public RespVo getSplit(HttpServletRequest request, String type, SplitType splitType) {
        log.info("查询自定义费率及上级自定义费率:{}",type);
        RespVo vo = new RespVo();
        try {
            Customer loginCustomer = getLoginCustomer( request);
            //Customer customer = customerService.queryById(loginCustomer.getId());

            //查询出所有下级
            List<Customer> customers = customerService.list(Wraps.<Customer>lbQ().eq(Customer::getPromoterId, loginCustomer.getId()));
            List<CustomerSplit> customerSplitList = customerSplitService.list(Wraps.<CustomerSplit>lbQ().eq(CustomerSplit::getCustomerId, loginCustomer.getId()).eq(CustomerSplit::getSplitType,splitType));
            JSONObject jsonObject = new JSONObject();
            if (customers.size() == customerSplitList.size()) {
                if ("1".equals(type)) {
                    //List<CustomerSplit> customerSplitSet = customerSplitService.list(Wraps.<CustomerSplit>lbQ().eq(CustomerSplit::getCustomerId, loginCustomer.getId()).eq(CustomerSplit::getStatus, "1").eq(CustomerSplit::getSplitType,splitType));
                    List<CustomerSplit> customerSplitSet = customerSplitService.getVerifyList(loginCustomer.getId(),"1",splitType);
                    jsonObject.put("customerSplit", customerSplitSet); // 自定义费率
                } else {
                    List<CustomerSplit> customerSplitSet = customerSplitService.getVerifyList(loginCustomer.getId(),"0",splitType);
                    jsonObject.put("customerSplit", customerSplitSet); // 自定义费率
                }
            } else {
                List<Long> customerSplitListId = new ArrayList<>();
                //先遍历下级用户  没有记录就填充
                for (CustomerSplit customerSplit : customerSplitList) {
                    customerSplitListId.add(customerSplit.getDownCustomerId());
                }
                for (Customer customer : customers) {
                    if (customerSplitListId.contains(customer.getId().toString()) == false) {
                        //没有记录
                        CustomerSplit customerSplit = new CustomerSplit();
                        customerSplit.setCustomerId(loginCustomer.getId());
                        customerSplit.setSplitRate(0L);
                        customerSplit.setSplitType(splitType);
                        customerSplit.setDownCustomerId(customer.getId());
                        customerSplit.setDownCustomerPhone(customer.getLoginName());
                        customerSplit.setStatus("0");
                        customerSplitService.save(customerSplit);
                    }
                }
                if ("1".equals(type)) {
                    List<CustomerSplit> customerSplitSet = customerSplitService.getVerifyList(loginCustomer.getId(),"1",splitType);
                    jsonObject.put("customerSplit", customerSplitSet); // 自定义费率
                } else {
                    List<CustomerSplit> customerSplitSet = customerSplitService.getVerifyList(loginCustomer.getId(),"0",splitType);
                    jsonObject.put("customerSplit", customerSplitSet); // 自定义费率
                }
            }
            BigDecimal limitSplit = null;
            CustomerSplit promoterSPlit = customerSplitService.getOne(Wraps.<CustomerSplit>lbQ().eq(CustomerSplit::getDownCustomerId,loginCustomer.getId()).eq(CustomerSplit::getSplitType,splitType));
            if(promoterSPlit == null || "0".equals(promoterSPlit.getStatus())){
                limitSplit = BigDecimal.ZERO;
            }else{
                limitSplit = promoterSPlit.getCurrRate();
            }
            jsonObject.put("limitSplit", limitSplit);
            vo.setResult(jsonObject);
            vo.setCode(RespVo.CODE_SUCCESS);
        } catch (Exception e) {
            vo.setCode(RespVo.CODE_ERROR);
            vo.setMessage("操作失败");
            log.error("操作失败", e);
        }
        return vo;
    }
}
